// <div id="app">Hello{{message}}</div>

/* 
{
  tag: 'div',
  attrs: [{id: 'app'}],
  children: [{tag: null, text: hello'}, {tag: 'div'}]
}
*/

var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/; // 属性
var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z]*"; // 标签名称
var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")"; // <span: xx>
var startTagOpen = new RegExp(("^<" + qnameCapture)); // 标签开头的正则，捕获的内容是标签名
var startTagClose = /^\s*(\/?)>/; // 匹配标签结束的 >
var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>")); // 匹配标签结尾的 </div>
var defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g; // {{}}

// 遍历
// 创建 ast语法树
function createASTElement(tag, attrs) {
  return {
    tag,
    attrs,
    children: [],
    type: 1,
    parent: null
  }
}
let root // 根元素
let createParent // 当前元素的父亲
// 数据结构 || 栈
// 开始标签、
let stack = []
function start(tag, attrs) {
  // console.log('开始的标签', tag , attrs);
  let element = createASTElement(tag, attrs)
  if(!root) {
    root = element
  }
  createParent = element
  stack.push(element)
}
// 文本标签
function charts(text) {
  // console.log('获取文本', text);
  // 替换空格
  text = text.replace(/a/g, '')
  if(text) {
    createParent.children.push({
      type: 3,
      text
    })
  }
}
// 结束标签
function end(tag) {
  // console.log('结束标签', tag);
  let element = stack.pop()
  createParent = stack[stack.length - 1]
  if(createParent)  {
    element.parent = createParent.tag
    createParent.children.push(element)
  }
}
export function parseHTML(html) {
  while(html) {
    // 判断标签<>
    let textEnd = html.indexOf('<') // 返回 0 就是个标签；不然就是 -1
    if(textEnd === 0) {
      // （1）开始标签
      const startTagMatch = parseStartTag() // 开始标签的内容
      if(startTagMatch) {
        start(startTagMatch.tagName, startTagMatch.attrs)
        continue
      }
      // （2）结束标签
      let endTagMatch = html.match(endTag)
      if(endTagMatch) {
        advance(endTagMatch[0].length)
        end(endTagMatch[1])
        continue
      }
    }
    // 文本
    let text = ''
    if(textEnd > 0) {
      // console.log('textEnd', textEnd);
      // 获取文本内容
      text = html.substring(0, textEnd)
      // console.log('text', text);
    }
    if(text) {
      advance(text.length)
      charts(text)
    }
  }
  function parseStartTag() {
    const start = html.match(startTagOpen) // 1结果 2false
    // console.log('start', start);
    if(start) {
      // 创建 ast 语法树
      let match = {
        tagName: start[1],
        attrs: []
      }
      // 删除 开始标签
      advance(start[0].length)
      // 属性，因为有多个属性，所以要进行遍历
      let attr
      let end
      while(!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
        // console.log('attr', attr);
        match.attrs.push({name: attr[1], value: attr[3] || attr[4] || attr[5]})
        advance(attr[0].length)
      }
      if(end) {
        // console.log('end', end);
        advance(end[0].length)
        return match
      }
    }
  }
  function advance(n) {
    html = html.substring(n)
    // console.log('删除html', html);
  }
  // console.log('root', root);
  return root
}